import {
  Breadcrumb,
  Button,
  Card,
  Form,
  Input,
  message,
  Modal,
  Radio,
  Space,
  Upload,
} from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import { Link } from 'react-router-dom';
import Channel from 'components/Channel';
//  下包  并引入包跟样式
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.snow.css';
import styles from './index.module.scss';
import { baseURL } from 'utils/request';
import { getToken } from 'utils/storage';
import { UploadOutlined } from '@ant-design/icons';
import {
  getArticleByIdApi,
  PublishArticleApi,
  updateArticleApi,
} from 'api/article';

// rfc
export default function ArticlePublish(_props) {
  // 声明一个ref来保存回显的数据
  const formRef = useRef({});
  // 声明一个保存草稿的ref
  const draftRef = useRef(false);
  // 声明type
  const [type, setType] = useState(1);
  // 声明按钮的显示于隐藏
  const [fileList, setFileList] = useState([]);
  // 声明存储图片
  const [imgSrc, setImgSrc] = useState('');
  const props = {
    name: 'image',
    // 文件上传框，默认支持的文件类型
    accept: '.png,.jpg',
    action: `${baseURL}/v1_0/upload`,
    headers: {
      authorization: `Bearer ${getToken()}`,
    },
    // 上传中、完成、失败都会调用这个函数。
    // file   fileList   event
    onChange(info) {
      // 在onChange中设置按钮的显示于隐藏
      setFileList(info.fileList);

      if (info.file.status === 'done') {
        message.success(`${info.file.name} 上传成功`, 1);
      } else if (info.file.status === 'error') {
        message.error(`${info.file.name} 上传失败`, 1);
      }
    },
    // 预览图片
    onPreview(file) {
      setImgSrc(file.thumbUrl || file.url); // 回填预览图片的地址
    },

    // 图片上传前的钩子函数
    beforeUpload(file) {
      // 这是声明类型的白名单
      const imgs = ['image/jpg', 'image/png'];
      // 阻止上传
      if (!imgs.includes(file.type)) {
        message.warning('不允许上传的文件类型', 1);
        // 阻止发请求，也不显示在页面上
        return Upload.LIST_IGNORE;
      }
    },
  };

  // 定义一个计算函数,设置切换type时显示的图片数量
  const showFileList = fileList.filter((item, index) => {
    if (type === 0) return false;
    if (type === 1) return index === 0;
    return true;
  });

  // changeValues 最近一个修改的值  。  allValue  所有的值
  const handleValuesChange = (changeValues, allValue) => {
    // 判断changeValues又type这个属性,且不为undefined的时候,setState更新type
    if (changeValues.type !== undefined) {
      setType(changeValues.type);
    }
  };

  const handleFinish = async (values) => {
    // 判定上传图片的数量
    if (showFileList.length !== type) {
      return message.warning('图片数量不对', 1);
    }

    // 为了跟后台数据一样,修改数据名跟删除一些数据名
    let formData = {
      ...values,
    };
    formData.cover = {
      // 转换type和images
      type: values.type,
      // images是url字符串组成的数组
      images: showFileList.map((item) => item.url || item.response.data.url),
    };
    // 删除没用的值
    delete formData.type;

    if (articleId) {
      // 编辑功能   传  id  data  草稿
      await updateArticleApi(articleId, formData, draftRef.current);
      message.success('编辑成功', 1);
    } else {
      // 发送发布请求    主动传参draftRef.current
      await PublishArticleApi(formData, draftRef.current);
      // 提示用户
      message.success('新增成功', 1);
    }

    // 跳转到内容管理页
    _props.history.push('/list');
  };

  // 3. 获取传来id
  const articleId = _props.match.params.id;

  const loacArticleById = async (id) => {
    const res = await getArticleByIdApi(id);
    // 将获取到的数据存到ref中       传上他的type值
    const infoRes = res.data.cover;
    formRef.current.setFieldsValue({ ...res.data, type: infoRes.type });
    // 回显type的状态值
    setType(infoRes.type);
    // 回显fileList，注意时对象组成的数组
    setFileList(infoRes.images.map((item) => ({ url: item })));
  };

  useEffect(() => {
    if (articleId) {
      loacArticleById(articleId);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <div style={{ height: '85vh', overflow: 'auto' }} className={styles.root}>
      <Card
        title={
          <Breadcrumb>
            <Breadcrumb.Item>
              <Link to={'/'}>首页</Link>
            </Breadcrumb.Item>
            <Breadcrumb.Item>
              {`${articleId ? '编辑' : '发布'}`}文章
            </Breadcrumb.Item>
          </Breadcrumb>
        }
      >
        <Form
          // 声明ref
          ref={formRef}
          labelCol={{ span: 4 }}
          onFinish={handleFinish}
          // 使用富文本框要设置的默认值
          initialValues={{
            content: '',
            type: 1,
          }}
          onValuesChange={handleValuesChange}
        >
          <Form.Item
            label="标题"
            name="title"
            rules={[
              {
                required: true,
                message: '请输入文章标题',
              },
            ]}
          >
            <Input placeholder="请输入文章标题" />
          </Form.Item>

          {/* 封装的下拉列表，频道的选择 */}
          <Form.Item
            label="频道"
            name="channel_id"
            rules={[
              {
                required: true,
                message: '请选择频道',
              },
            ]}
          >
            {/* allowClear  是鼠标移到选择框的时候触发的清除按钮 */}
            <Channel allowClear></Channel>
          </Form.Item>

          <Form.Item
            label="内容"
            name="content"
            rules={[
              {
                required: true,
                // 判断value的值为空，放回失败的信息
                validator: (_, value) => {
                  // 判断是否为空标签
                  // 使用自定义校验，放回Promise.resolve();表示通过  ，  Promise.reject();表示不通过
                  if (value === '<p><br></p>' || !value) {
                    return Promise.reject(new Error('内容不能为空'));
                  }
                  return Promise.resolve();
                },
              },
            ]}
          >
            {/* 使用富文本框 */}
            <ReactQuill theme="snow"></ReactQuill>
          </Form.Item>

          <Form.Item label="封面" name="type">
            <Radio.Group>
              <Radio value={1}>单图</Radio>
              <Radio value={3}>三图</Radio>
              <Radio value={0}>无图</Radio>
            </Radio.Group>
          </Form.Item>
          {/* 上传图片 */}
          <Form.Item wrapperCol={{ offset: 4 }} name="text">
            {/* // 声明按钮的显示于隐藏 ,将fileList放到Upload的props身上 */}
            <Upload {...props} listType="picture-card" fileList={showFileList}>
              {/* 将按钮改为受控组件,控制显示于隐藏 */}
              {fileList.length < type && <UploadOutlined />}
            </Upload>
          </Form.Item>

          <Form.Item wrapperCol={{ offset: 4 }}>
            <Space>
              <Button size="large" type="primary" htmlType="submit">
                {`${articleId ? '编辑' : '发布'}`}文章
              </Button>
              <Button
                size="large"
                type="primary"
                htmlType="submit"
                // 点击时改变ref存储draft的值为true  htmlType设置为submit让他冒泡
                onClick={() => (draftRef.current = true)}
              >
                存入草稿
              </Button>
            </Space>
          </Form.Item>
        </Form>
        {/* 模态框 */}
        <Modal
          // 弹框顶部的文字
          title="预览图片"
          // 对话框的显示于隐藏
          visible={!!imgSrc}
          // 去除底部
          footer={null}
          // 点击X关闭弹框
          onCancel={() => setImgSrc('')}
        >
          <img width={480} style={{ objectFit: 'cover' }} src={imgSrc} alt="" />
        </Modal>
      </Card>
    </div>
  );
}
